// file: send_message.c
//
// compile with:
//  $ gcc -o send_message send_message.c -llcm
//
// If using GNU/Linux, you can also use pkg-config:
//  $ gcc -o send_message send_message.c `pkg-config --cflags --libs lcm`

#include <stdio.h>
#include <stdlib.h>
#include <lcm/lcm.h> 
#include <string.h>
#include <time.h>
#include "example_t.h"

/* User Defined Variable --
 * Change this to tweak speeds for multicasting on your network
 * Lower values mean faster speeds, but a higher chance for packet loss
 * Higher values mean slower speeds, but more reliable transmission
 * 100 = 1 second
 * 10 = .1 second
 */
const int PACKET_DELAY = 10; //delay in seconds between each packet (default = 10)

//struct for the data
typedef struct {
	char * location;
	unsigned long int read_length;
} data_handle;


//procedure to send input data on lcm socket
static void send_message (lcm_t * lcm, data_handle my_data_handle, char* message_id)
{
	int i;
	int j;
	int max_packet_size = 64000;
	char * packet_data = malloc(sizeof(char)*max_packet_size);

	int number_of_packets = (my_data_handle.read_length-1)/max_packet_size+1;
	int last_packet_size;

	for (i=0; i<number_of_packets; i++)
	{
		//assign data to packet
		example_t my_data = {
		.message_id = message_id,
		.bytes_in_message = my_data_handle.read_length,
		.packet_id = i+1,
		.number_of_packets = number_of_packets,
		.max_bytes_in_packet = max_packet_size,
		};
	
		if (i<number_of_packets-1)
		{
			my_data.bytes_in_packet = max_packet_size;
			for (j=0; j<max_packet_size; j++)
			{			
				*(packet_data+j)=*(my_data_handle.location+i*max_packet_size+j);
			}
		}
		else
		{
			last_packet_size = my_data_handle.read_length%max_packet_size;
			if (last_packet_size == 0) last_packet_size = 10;
			my_data.bytes_in_packet = last_packet_size;

			for (j=0; j<last_packet_size; j++)
			{			
				*(packet_data+j)=*(my_data_handle.location+i*max_packet_size+j);
			}
		}

		my_data.frame_data = packet_data;
		
		example_t_publish (lcm, "EXAMPLE", &my_data);
		usleep(PACKET_DELAY*10000); //packet delay (time to wait before sending next packet)
	}

	free(packet_data);
}

//function to read data from file into memory
data_handle read_file(char filename[]) 
{
	data_handle my_data_handle;
  	FILE * ifp;
	long lSize;
	char * buffer;
	size_t result; 

	//create NULL handle for return if the file cannot be read	
	data_handle null_handle;
	null_handle.location = NULL;
	null_handle.read_length = 0;

	//strange code here!!!  think it is unnecessary
  	if (filename=="NULL")
	{
		puts("Filename is Null.");
		return null_handle;
	}

	//open input file	
	ifp = fopen ( filename, "rb" );
	if (ifp==NULL) {fputs ("File error",stderr); exit (1);}

	// obtain file size:
	fseek (ifp , 0 , SEEK_END);
	lSize = ftell (ifp);
	rewind (ifp);

	// allocate memory to contain the whole file:
	buffer = (char*) malloc (sizeof(char)*lSize);
	if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

	// copy the file into the buffer:
	result = fread (buffer,1,lSize,ifp);
	if (result != lSize) {fputs ("Reading error",stderr); exit (3);}

	//display size of file
	printf("Total buffer size: %zu bytes\n", result);

	// the whole file is now loaded in the memory buffer
	
  	my_data_handle.read_length = (unsigned long int) result;
	my_data_handle.location = buffer;
	
	// terminate
	fclose (ifp);

	//do not free the buffer yet- it is used by the calling function!!
	//free (buffer);
	
	return my_data_handle;
}

//test function to output data read from file to screen
static void test_handle(data_handle my_data_handle)
{
	int i;
	printf("Testing data handle...\n");
	for (i=0; i<my_data_handle.read_length; i++)
	{
		printf("%c", *(my_data_handle.location+i));
	}
	printf ("\n");
}




int send_video (char *filename)
{
	char* videofilename = (char*)malloc(sizeof(char)*512);
	strcpy(videofilename,"tmpsplit/");
	strcat(videofilename,filename);

	//initialize lcm socket	    	
	lcm_t * lcm;
    	lcm = lcm_create (NULL);
    	if (!lcm) return 1;

	//read data from file
	printf("Reading file\n");
	data_handle my_data_handle = read_file(videofilename);
	printf("File read\n");
	//test data handle (output data to screen!)
	//test_handle(my_data_handle);

	//send data
	send_message (lcm, my_data_handle, filename);

	//free memory (buffer) used to store data
	free(my_data_handle.location);

	//destroy lcm socket
    	lcm_destroy (lcm);
    	return 0;
}
